package top.malaoshi.data;

/**
 * 创建高级查询，查询后返回DataTable
 */
public class DataAdvancedQuery {
    protected DataTable dataTable;
    /**
     * 查询结果 DataTable
     */
    private DataTable dataTableTemp;
    protected DataAdvancedQuery(DataTable dataTable) {
        this.dataTable = dataTable;
    }

    /**
     * 查询列
//     * @param columns
     * @return
     */
//    public DataQuery select(String ... columns){
//
//        dataTableTemp = new DataTable(this.dataTable.getTableName());
//
//        for(String column : columns){
//            DataColumn dataColumn = dataTable.columns.get(column);
//            dataTableTemp.columns.add(dataColumn.getName(),dataColumn.getType());
//        }
//
//        return this;
//    }

    /**
     * 查询所有列
     * @return
     */
    public DataAdvancedQuery select(){

        dataTableTemp = new DataTable(this.dataTable.getName());

        for(int i = 0,count = this.dataTable.columns().count();i<count;i++){
            DataColumn dataColumn = this.dataTable.columns().get(i);
            this.dataTableTemp.columns().add(dataColumn.getName(),dataColumn.getType());
        }
        return this;
    }

    public DataAdvancedQuery filter(String columnName, DataQuery.Option option, Object value){
        DataColumn dataColumn = dataTable.columns().get(columnName);
        // 如果列类型是int
        if(dataColumn.getType() == DataColumn.Type.INT){
            if(value instanceof Integer){ // 如果传入的是 int 类型，直接调用 toIntAndFilter()
                return toIntAndFilter(columnName, option, (Integer)value);
            }else if(value instanceof Double){ // 如果传入的是 double类型，调用 toDoubleAndFilter()
                return toDoubleAndFilter(columnName,option,(Double)value);
            }else if(value instanceof String){ // 如果传入的是 string 类型，调用 toIntAndFilter
                return toIntAndFilter(columnName,option,Integer.parseInt((String)value));
            }else{
                throw new DataColumnTypeMismatchException(columnName,dataColumn.getType(),value);
            }
        }else if(dataColumn.getType() == DataColumn.Type.DOUBLE){ // 如果列类型是 double
            if(value instanceof Integer){ // 如果传入的是 int 类型，调用 toDoubleAndFilter ()
                return toDoubleAndFilter(columnName, option,Double.parseDouble(value.toString()));
            }else if(value instanceof Double){ // 如果传入的是 double类型，调用 toDoubleAndFilter()
                return toDoubleAndFilter(columnName,option,(Double)value);
            }else if(value instanceof String){ // 如果传入的是 string 类型，调用 filterInt
                return toDoubleAndFilter(columnName,option,Double.parseDouble((String)value));
            }else{
                throw new DataColumnTypeMismatchException(columnName,dataColumn.getType(),value);
            }
        }else if(dataColumn.getType() == DataColumn.Type.TEXT){ // 如果列类型是字符串
            if(value instanceof Integer){ // 如果传入的是 int 类型，调用 toStringAndFilter ()
                return toStringAndFilter(columnName, option,value.toString());
            }else if(value instanceof Double){ // 如果传入的是 double类型，调用 toStringAndFilter()
                return toStringAndFilter(columnName,option,value.toString());
            }else if(value instanceof String){ // 如果传入的是 string 类型，调用 toStringAndFilter
                return toStringAndFilter(columnName,option,(String)value);
            }else{
                throw new DataColumnTypeMismatchException(columnName,dataColumn.getType(),value);
            }
        }
        return null;
    }

    /**
     * 将列值转成 int 类型再比较
     * @param columnName
     * @param option
     * @param value
     * @return
     */
    private DataAdvancedQuery toIntAndFilter(String columnName, DataQuery.Option option, int value){
        int columnsIndex = dataTable.columns().getIndex(columnName);
        for(DataRow row: dataTable.rows().rowList){
            Integer v = row.getIntValue(columnsIndex);// 取出数据
            if( option == DataQuery.Option.gt     ||
                option == DataQuery.Option.gte    ||
                option == DataQuery.Option.lt     ||
                option == DataQuery.Option.lte    ||
                option == DataQuery.Option.eq     ||
                option == DataQuery.Option.neq){

                if (    (option == DataQuery.Option.gt && v > value) ||
                        (option == DataQuery.Option.gte && v >= value) ||
                        (option == DataQuery.Option.lt && v < value )||
                        (option == DataQuery.Option.lte && v <= value )||
                        (option == DataQuery.Option.eq && v == value )||
                        (option == DataQuery.Option.neq && v != value )
                ) {
                    dataTableTemp.rows().add(row.toArray());
                }
            }else{
                throw new DataQueryNotOptionException(option,value);
            }
        }
        afterFilter();
        return this;
    }
    /**
     * 查询后，根据 dataTableTemp 的列和数据创建对象，并将该对象赋值给 dataTable 中
     * 不能将 dataTableTemp 引用赋值给 dataTable，否则两个引用指向同一个对象
      */

    private void afterFilter(){
        this.dataTable = this.dataTableTemp.copy();

        select();

    }

    /**
     * 将列值转成 double 类型再比较
     * @param columnName
     * @param option
     * @param value
     * @return
     */
    private DataAdvancedQuery toDoubleAndFilter(String columnName, DataQuery.Option option, double value){
        int columnsIndex = dataTable.columns().getIndex(columnName);
        for(DataRow row: dataTable.rows().rowList){
            Double v = row.getDoubleValue(columnsIndex);// 取出数据
            if( option == DataQuery.Option.gt     ||
                option == DataQuery.Option.gte    ||
                option == DataQuery.Option.lt     ||
                option == DataQuery.Option.lte    ||
                option == DataQuery.Option.eq     ||
                option == DataQuery.Option.neq){

                if (    (option == DataQuery.Option.gt && v > value) ||
                        (option == DataQuery.Option.gte && v >= value) ||
                        (option == DataQuery.Option.lt && v < value )||
                        (option == DataQuery.Option.lte && v <= value )||
                        (option == DataQuery.Option.eq && v == value )||
                        (option == DataQuery.Option.neq && v != value )
                ) {
                    dataTableTemp.rows().add(row.toArray());
                }
            }else{
                throw new DataQueryNotOptionException(option,value);
            }


        }
        afterFilter();
        return this;
    }

    /**
     * 将列值转成 string 类型再比较
     * @param columnName
     * @param option
     * @param value
     * @return
     */
    private DataAdvancedQuery toStringAndFilter(String columnName, DataQuery.Option option, String value){
        int columnsIndex = dataTable.columns().getIndex(columnName);
        for(DataRow row: dataTable.rows().rowList){
            String v = row.getStringValue(columnsIndex);// 取出数据
            if (    (option == DataQuery.Option.contain && v.contains(value))     ||
                    (option == DataQuery.Option.start && v.startsWith(value))     ||
                    (option == DataQuery.Option.end && v.endsWith(value) )        ||
                    (option == DataQuery.Option.eq && v.equals(value) )           ||
                    (option == DataQuery.Option.neq && !v.equals(value))          ||
                    (option == DataQuery.Option.lt && v.compareTo(value) < 0)     ||
                    (option == DataQuery.Option.lte && v.compareTo(value) <= 0)   ||
                    (option == DataQuery.Option.gt && v.compareTo(value) > 0)     ||
                    (option == DataQuery.Option.gte && v.compareTo(value) >= 0)

            ) {
                dataTableTemp.rows().add(row.toArray());
            }
        }
        afterFilter();
        return this;
    }
    /**
     * 获取结果
     * @return
     */
    public DataTable getResult(){
        return dataTable;
    }
    
}
